package com.rfsp.common.shiro;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
//import org.springframework.session.FindByIndexNameSessionRepository;
//import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
import org.springframework.stereotype.Component;

import com.rfsp.common.pojo.po.OrgPO;
import com.rfsp.common.pojo.po.UserPO;
import com.rfsp.common.pojo.vo.PrivilegeVO;
import com.rfsp.common.pojo.vo.UserVO;

@Component
public class ShiroUtils {
	
	// 全部登录中用户角色缓存 session级缓存
	private static Map<String, Set<String>> userRoles = new HashMap<String, Set<String>>();

	// 全部登录中用户权限url缓存 session级缓存
	private static Map<String, Set<String>> userPerms = new HashMap<String, Set<String>>();

	// 按角色存储权限url
	private static Map<String, Set<String>> rolePerms = new HashMap<String, Set<String>>();

	// 系统所有角色用户权限树 根据角色缓存 全局缓存
	private static Map<String, List<PrivilegeVO>> rightTree = new HashMap<String, List<PrivilegeVO>>();

	public static List<PrivilegeVO> getRightTree(String user) {
		return rightTree.get(user);
	}

	private static String areaCodes = "";
	
	public static String getAreaCodes() {
		return areaCodes;
	}

	public static void setAreaCodes(String areaCodes) {
		ShiroUtils.areaCodes = areaCodes;
	}

	public static void setRightTree(String user, List<PrivilegeVO> perms) {
		rightTree.put(user, perms);
	}

	// 添加登录用户角色到缓存
	public static void addRoleCodes(String usercode, Set<String> role) {
		userRoles.put(usercode, role);
	}

	// 清除用户角色缓存
	public static void removeRoleCodes(String usercode) {
		userRoles.remove(usercode);
	}

	// 清除用户所有角色缓存
	public static void clearRoleCodes() {
		userRoles.clear();
	}

	// 返回用户角色
	public static Set<String> getRoles(String usercode) {
		return userRoles.get(usercode);
	}

	// 返回用户权限
	public static Set<String> getRolePerms(String roleCode) {
		return rolePerms.get(roleCode);
	}

	// 获取所有登陆用户的权限
	public static Map<String, Set<String>> getRolePerms() {
		return rolePerms;
	}

	// 删除所有登陆用户的权限
	public static void clearRolePerms() {
		rolePerms.clear();
	}

	// 添加登录用户权限到缓存
	public static void addRolePerms(String roleCode, Set<String> url) {
		rolePerms.put(roleCode, url);
	}

	// 清除用户权限缓存
	public static void removeRolePerms(String roleCode) {
		rolePerms.remove(roleCode);
	}

	// 设置每个用户的树
	public static Set<String> getUserRightUrl(Set<String> roleCodes) {
		Set<String> url = new HashSet<String>();
		if (null != roleCodes && !roleCodes.isEmpty()) {
			for (String code : roleCodes) {
				url.addAll(ShiroUtils.getRolePerms(code));
			}
		}
		url.remove(null);
		return url;
	}

	// 返回用户权限
	public static Set<String> getUserPerms(String usercode) {
		return userPerms.get(usercode);
	}

	// 获取所有登陆用户的权限
	public static Map<String, Set<String>> getAllUserPerms() {
		return userPerms;
	}

	// 添加登录用户权限到缓存
	public static void addUserPerms(String usercode, Set<String> permSet) {
		userPerms.put(usercode, permSet);
	}

	// 清除用户权限缓存
	public static void removeUserPerms(String usercode) {
		userPerms.remove(usercode);
	}
	
	/**
	 * 
	 * @return
	 */
	public static Session getSession() {
		return SecurityUtils.getSubject().getSession();
	}
	public static <T> T getAttribute(String key) {
		return (T)getSession().getAttribute(key);
	}
	public static <T> T get(String key) {
		return getAttribute(key);
	}
	 public static void put(Object key, Object value){ 
		 setAttribute(key, value);
	 }
    public static void setAttribute(Object key, Object value){  
        Subject currentUser = SecurityUtils.getSubject();  
        if(null != currentUser){  
            Session session = currentUser.getSession();  
            if(null != session){
                session.setAttribute(key, value); 
            }  
        }  
    }  
    
    public static void removeSession(Object key){  
        Subject currentUser = SecurityUtils.getSubject();  
        if(null != currentUser){  
            Session session = currentUser.getSession();  
            if(null != session){
                session.removeAttribute(key); 
            }  
        }  
    }  
    
    public static UserPO getCurrentUser(){
    	Object obj =  ShiroUtils.getAttribute("user");
    	return (UserPO) obj;
    }
    
    public static OrgPO getCurrentOrg(){
    	Object obj =  ShiroUtils.getAttribute("org");
    	return (OrgPO)obj;
    }
    
    public static UserVO getUserVO(){
    	Object obj =  ShiroUtils.getAttribute(getUserCode());
    	return (UserVO) obj;
    }
    
    public static OrgPO getOrgPO(){
    	Object obj =  ShiroUtils.getAttribute("org");
    	return (OrgPO)obj;
    }
    
	/**
	 * get session Id from current user
	 * @return
	 */
	public static String getSessionId() {
		Session session = getSession();
		if (null == session) {
			return null;
		}
		return getSession().getId().toString();
	}
	
	/**
	 * 踢除用户，防止异地登录，考虑同一session同一userCode和同一session不同userCode的情况
	 * @param currentSessionId 当前浏览器的sessionId，用于防止同一个用户重复登录而被剔除
	 * @param username zhucefei_fapiao
	 */
	private static boolean kickOutUser(String username,String currentSessionId){
		
		//删除同一session不同userCode的属性值，但保留原有session——>对应同一session情况下切换不同用户登录的场景。
		List<String> principalNameList = null;//= jdbcOperationsSessionRepository.getPrincipalNameBySessionId(currentSessionId);
		if(principalNameList.size() > 0 && !principalNameList.contains(username)){
			
			Subject loginedSubject = getSubject();
			// 清除已登陆账户的角色缓存
			ShiroUtils.removeRoleCodes((String)loginedSubject.getPrincipal());
			// 清除已登陆账户的权限缓存
			ShiroUtils.removeUserPerms((String)loginedSubject.getPrincipal());
			//切换到新账户，需要将之前的登陆账户退出,重新换一个session。
			loginedSubject.logout();
		}
		
		//凡登录之前，均要先踢出相同userCode的session记录
		//但同一session同一userCode不踢出，需要踢出不同session但相同userCode的session记录
//		jdbcOperationsSessionRepository.removeSpringSessionByPrincipalName(username,currentSessionId);
		
		return true;
	}
	
	/**踢除用户,不考虑任何情况， 在以下场景会使用到：<br/>
	 * 新增权限：{@link com.rfp.common.service.right.impl.PrivilegeManageImpl#addPrivilege(PrivilegeVO , Map)}<br/>
	 * 修改权限：{@link com.rfp.common.service.role.impl.RoleManageImpl#updateRole(UserPO, Role[],  Map)}<br/>
	 * 菜单访问权限过期校验{@link com.rfp.common.filter.CustomAccessControlFilter#onAccessDenied(ServletRequest, ServletResponse)}<br/>
	 * @param username
	 */
	public static boolean kickOutUser(String username){
		
		Subject loginedSubject = getSubject();
		// 清除已登陆账户的角色缓存
		ShiroUtils.removeRoleCodes((String)loginedSubject.getPrincipal());
		// 清除已登陆账户的权限缓存
		ShiroUtils.removeUserPerms((String)loginedSubject.getPrincipal());
		//切换到新账户，需要将之前的登陆账户退出,重新换一个session。
		loginedSubject.logout();
		return true;
	}

	/**
	 * 判断当前用户是否已通过认证
	 * @return
	 */
	public static boolean hasAuthenticated() {
		return getSubject().isAuthenticated();
	}

	public static Subject getSubject() {
		return SecurityUtils.getSubject();
	}

	public static String getUserCode(){
		return null == getSubject().getPrincipal() ? "" : getSubject().getPrincipal().toString(); 
	}

}